package com.Java.train.business.service.daily.Impl;

import cn.hutool.core.date.DateUtil;
import com.Java.train.business.entity.*;
import com.Java.train.business.entity.DTO.DailyTrainDTO;
import com.Java.train.business.req.DailyTrainStationReq;
import com.Java.train.business.service.TrainStationService;
import com.Java.train.common.response.CommonResp;
import com.Java.train.business.entity.DTO.DailyTrainStationDTO;
import com.Java.train.business.req.daily.DailyTrainStationQueryReq;
import com.Java.train.common.exception.BusniessException;
import com.Java.train.common.exception.BusniessExceptionEnum;
import com.Java.train.common.response.PageResp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.Java.train.business.mapper.DailyTrainStationMapper;
import com.Java.train.business.service.daily.DailyTrainStationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import com.Java.train.common.context.LoginMemberContext;
import com.Java.train.common.utils.SnowFlakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.date.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;
import java.util.Arrays;
import java.util.Collections;
/**
* 每日车站 服务实现类
*
* @author luomoxingchen
* @since 2024-09-24
*/
@Service
public class DailyTrainStationServiceImpl extends ServiceImpl<DailyTrainStationMapper, DailyTrainStation> implements DailyTrainStationService {

    private static final Logger LOG = LoggerFactory.getLogger(DailyTrainStationService.class);

    @Autowired
    DailyTrainStationMapper dailyTrainStationMapper;

    @Resource
    TrainStationService trainStationService;

    @Override
    public PageResp<DailyTrainStationDTO> queryList(DailyTrainStationQueryReq dailyTrainStationQueryReq){
        // 1.获取当前用户id信息
        //        Long id = LoginMemberContext.getId();
        String trainCode = dailyTrainStationQueryReq.getTrainCode();
        Date date = dailyTrainStationQueryReq.getDate();
        // 2.查询数据库中是否存在当前信息（id）
        LOG.info("查询页码：{}", dailyTrainStationQueryReq.getPage());
        LOG.info("每页条数：{}", dailyTrainStationQueryReq.getSize());
        // 判重
        List<DailyTrainStation> dailyTrainStations = null;
        if(StrUtil.isNotBlank(trainCode) || ObjectUtil.isNotEmpty(date)){
            dailyTrainStations = getDailyTrainStationByCondition(trainCode, date);
        }else {
            dailyTrainStations = list();
        }

        if(dailyTrainStations == null || CollUtil.isEmpty(dailyTrainStations)){
            // 返回空列表
            return new PageResp<DailyTrainStationDTO>();
//            throw new BusniessException(BusniessExceptionEnum.MEMBER_PASSENGER_NOT_EXITS);
        }

        // 3 分析分页信息
        // 3.1 获取分页总条数和页数
        PageInfo<DailyTrainStation> pageInfo = new PageInfo<>(dailyTrainStations);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        // 3.2 转为封装后的返回值并封装到分页返回值中
        List<DailyTrainStationDTO> list = BeanUtil.copyToList(dailyTrainStations, DailyTrainStationDTO.class);
        PageResp<DailyTrainStationDTO> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(list);
        // 4.返回查询到的信息
        return pageResp;
    }

    @Override
    public CommonResp<Object> modify(DailyTrainStation dailyTrainStation) {
        Long id = dailyTrainStation.getId();
        DateTime dateTime = DateTime.now();
        if(ObjectUtil.isNull(id)){
            // 查重
            long trainStationCount = getTrainStationCount(dailyTrainStation.getTrainCode(), dailyTrainStation.getName(), dailyTrainStation.getDate());
            if(trainStationCount > 0){
                throw new BusniessException(BusniessExceptionEnum.BUSINESS_TRAINSTATION_ALREADY_EXITS);
            }
            // 查idx和traincode
            DailyTrainStation trainStationDB = getTrainStationByTrainCodeAndIdx(dailyTrainStation.getTrainCode(), dailyTrainStation.getIdx(), dailyTrainStation.getDate());
            if(ObjectUtil.isNotEmpty(trainStationDB)){
                throw new BusniessException(BusniessExceptionEnum.BUSINESS_TRAINSTATION_ALREADY_EXITS);
            }

            // 查name和traincode
            DailyTrainStation trainStationDB1 = getTrainStationByTrainCodeAndName(dailyTrainStation.getTrainCode(), dailyTrainStation.getName(), dailyTrainStation.getDate());
            if(ObjectUtil.isNotEmpty(trainStationDB1)){
                throw new BusniessException(BusniessExceptionEnum.BUSINESS_TRAINSTATION_ALREADY_EXITS);
            }

            dailyTrainStation.setId(SnowFlakeUtil.getSnowFlakeNextId());
            dailyTrainStation.setCreateTime(dateTime);
            dailyTrainStation.setUpdateTime(dateTime);
            boolean save = save(dailyTrainStation);
            return new CommonResp<>(save);
        } else {
            dailyTrainStation.setUpdateTime(dateTime);
            boolean update = updateById(dailyTrainStation);
            return new CommonResp<>(update);
        }
    }

    @Override
    public CommonResp<Object> remove(String ids) {
        if(StrUtil.isNotEmpty(ids)){
            String[] array = ids.split(",");
            if(!CollectionUtils.isEmpty(Arrays.asList(array))) {
                return new CommonResp<>(dailyTrainStationMapper.deleteBatchIds(Arrays.asList(array)));
            }
        }
        return new CommonResp<>(Collections.EMPTY_LIST);
    }

    @Override
    public void genDaily(Date date, String trainCode) {
        LOG.info("生成日期为[{}]车次编号为[{}]的车站数据开始", DateUtil.formatDate(date), trainCode);
        // 1.查询是否存在火车
        LambdaQueryWrapper<TrainStation> wrapper = new LambdaQueryWrapper<>();
        List<TrainStation> carriages = trainStationService.list(wrapper.eq(TrainStation::getTrainCode, trainCode)
                .orderBy(true, true, TrainStation::getIdx));
        if(CollUtil.isEmpty(carriages)) {
            LOG.info("没有火车车厢信息");
//            throw new BusniessException(BusniessExceptionEnum.BUSINESS_TRAINSTATION_NOT_EXITS);
        }

        // 2.复制生成dailyTrain
        List<DailyTrainStation> dailyTrainCarriages = BeanUtil.copyToList(carriages, DailyTrainStation.class);
        // 2.1 删除之前生成的火车车厢(直接删一个车厢）
        LambdaQueryWrapper<DailyTrainStation> dailyWrapper = new LambdaQueryWrapper<>();
        remove(dailyWrapper.eq(DailyTrainStation::getTrainCode, trainCode).eq(DailyTrainStation::getDate, date));

        DateTime dateTime = DateTime.now();
        for (DailyTrainStation dailyTrainStation : dailyTrainCarriages) {
            // 2.2 生成每日车厢
            dailyTrainStation.setId(SnowFlakeUtil.getSnowFlakeNextId());
            dailyTrainStation.setCreateTime(dateTime);
            dailyTrainStation.setUpdateTime(dateTime);
            dailyTrainStation.setDate(date);
            save(dailyTrainStation);
        }
        LOG.info("生成日期为[{}]车次编号为[{}]的车站数据结束", DateUtil.formatDate(date), trainCode);
    }

     /**
      * @Description: 实现查询当日车次所经过的所有车站
      * @param
      * @return
      */
    @Override
    public List<DailyTrainStationDTO> queryAllByTrain(DailyTrainStationReq dailyTrainStationReq) {
        Date date = dailyTrainStationReq.getDate();
        String trainCode = dailyTrainStationReq.getTrainCode();
        LambdaQueryWrapper<DailyTrainStation> wrapper = new LambdaQueryWrapper<>();
        List<DailyTrainStation> list = list(wrapper.eq(DailyTrainStation::getDate, date).eq(DailyTrainStation::getTrainCode, trainCode)
                .orderBy(true, true, DailyTrainStation::getIdx));
        List<DailyTrainStationDTO> dailyTrainStationDTOS = BeanUtil.copyToList(list, DailyTrainStationDTO.class);
        return dailyTrainStationDTOS;
    }


    // 通过唯一键校验查重
    private List<DailyTrainStation> getDailyTrainStationByCondition(String trainCode, Date date) {
        LambdaQueryWrapper<DailyTrainStation> wrapper = new LambdaQueryWrapper<>();
        List<DailyTrainStation> list = null;
        if(StrUtil.isNotBlank(trainCode) && ObjectUtil.isEmpty(date)){
            list = list(wrapper.eq(DailyTrainStation::getTrainCode, trainCode).orderBy(true, true, DailyTrainStation::getTrainCode));
        } else if(ObjectUtil.isNotEmpty(date) && StrUtil.isBlank(trainCode)){
            list = list(wrapper.eq(DailyTrainStation::getDate, date).orderBy(true, true, DailyTrainStation::getDate));
        } else{
            list = list(wrapper.eq(DailyTrainStation::getTrainCode, trainCode).eq(DailyTrainStation::getDate, date).orderBy(true, true, DailyTrainStation::getDate, DailyTrainStation::getTrainCode));
        }
        return list;
    }


    // 通过唯一键校验查重
    private DailyTrainStation getTrainStationByTrainCodeAndIdx(String trainCode, Integer idx, Date date) {
        LambdaQueryWrapper<DailyTrainStation> wrapper = new LambdaQueryWrapper<>();
        DailyTrainStation one = getOne(wrapper.eq(DailyTrainStation::getTrainCode, trainCode).eq(DailyTrainStation::getIdx, idx).eq(DailyTrainStation::getDate, date));
        return one;
    }
    private DailyTrainStation getTrainStationByTrainCodeAndName(String trainCode, String name, Date date) {
        LambdaQueryWrapper<DailyTrainStation> wrapper = new LambdaQueryWrapper<>();
        DailyTrainStation one = getOne(wrapper.eq(DailyTrainStation::getTrainCode, trainCode).eq(DailyTrainStation::getName, name).eq(DailyTrainStation::getDate, date));
        return one;
    }

    private long getTrainStationCount(String trainCode, String name, Date date){
        LambdaQueryWrapper<DailyTrainStation> wrapper = new LambdaQueryWrapper<>();
        long count = count(wrapper.eq(DailyTrainStation::getTrainCode, trainCode).eq(DailyTrainStation::getName, name).eq(DailyTrainStation::getDate, date));
        return count;
    }
}


